package com.hejia.alauda.service;

import static com.hejia.alauda.entity.Award.CREDIT_2000;
import static com.hejia.alauda.entity.Award.PHONE_CHARGE;
import static com.hejia.alauda.entity.Award.THANKS;
import static com.hejia.alauda.entity.Qualification.TYPE_BONUS_20150415;
import static com.hejia.alauda.entity.Qualification.TYPE_MARCH_TRAFFIC_20150328;
import static com.hejia.alauda.entity.Qualification.TYPE_ZERO_BAIHE_GIFT_SEASON_1;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_GROUP_BUYING_FOUNDER;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_GROUP_BUYING_QUEUE;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_HEJIA_LOTTERY_ACCUMULATED_AMOUNT;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_HUSHEN_300_CALCULATE_DATE;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_USER_HUSHEN_300_DATE;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_USER_HUSHEN_300_FINANCING_RECORD;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_USER_HUSHEN_300_INCOME;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_USER_YOUKU_INVITE;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_USER_ZERO_YUAN;
import static com.hejia.alauda.event.EventConstant.MONGODB_KEY_USER_ZERO_YUAN_SHOW;
import static com.hejia.alauda.event.EventConstant.REDIS_KEY_CHILDRENS_DAY_2015_CONFIG;
import static com.hejia.alauda.event.EventConstant.REDIS_KEY_SENDED_USER_ID;
import static com.hejia.alauda.event.EventConstant.TRACK_HJ_MM_GROUP_BUYING_IPHONE6S;
import static com.hejia.alauda.event.EventConstant.TRACK_HJ_MM_GROUP_BUYING_PAN;
import static com.hejia.alauda.event.EventConstant.TRACK_HJ_MM_GROUP_BUYING_SHARE_IPHONE6S;
import static com.hejia.alauda.event.EventConstant.TRACK_HJ_MM_GROUP_BUYING_SHARE_PAN;
import static com.hejia.alauda.event.EventConstant.TRACK_HJ_MM_HEJIA_LOTTERY;
import static com.hejia.alauda.event.EventConstant.TRACK_HJ_MM_ZERO_YUAN_APPLE_WATCH;
import static com.hejia.alauda.event.EventConstant.TRACK_HJ_MM_ZERO_YUAN_IPHONE_6S_16G;
import static com.hejia.alauda.event.EventConstant.TRACK_HJ_MM_ZERO_YUAN_PHILIPS_TACHOGRAPH;
import static com.hejia.alauda.utils.DateTimeUtil.getMaxDateStr;
import static com.hejia.alauda.utils.DateTimeUtil.getMinDateStr;
import static com.hejia.alauda.utils.Utils.MYSQL_DATE_FORMAT;
import static com.hejia.alauda.utils.Utils.TIME_2015_04_01;
import static com.hejia.alauda.utils.Utils.formatDate;
import static com.hejia.alauda.utils.Utils.formatDateTime;
import static com.hejia.alauda.utils.Utils.readValue;
import static org.apache.commons.lang3.StringUtils.indexOf;
import static org.apache.commons.lang3.StringUtils.isNoneBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.lastIndexOf;
import static org.apache.commons.lang3.StringUtils.substring;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.apache.commons.lang3.time.DateUtils.addDays;
import static org.apache.commons.lang3.time.DateUtils.addHours;
import static org.apache.commons.lang3.time.DateUtils.addMinutes;
import static org.apache.commons.lang3.time.DateUtils.addSeconds;
import static org.springframework.util.CollectionUtils.isEmpty;
import static org.springframework.util.NumberUtils.parseNumber;
import static org.springframework.util.ReflectionUtils.findMethod;
import static org.springframework.util.ReflectionUtils.invokeMethod;
import static org.springframework.util.StringUtils.collectionToDelimitedString;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.annotation.Resource;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.util.LinkedCaseInsensitiveMap;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hejia.alauda.convert.DataHandler;
import com.hejia.alauda.convert.RowMapper;
import com.hejia.alauda.entity.Activity;
import com.hejia.alauda.entity.Address;
import com.hejia.alauda.entity.Award;
import com.hejia.alauda.entity.BonusRecord;
import com.hejia.alauda.entity.Financing;
import com.hejia.alauda.entity.Invitation;
import com.hejia.alauda.entity.OrderSerial;
import com.hejia.alauda.entity.Parameter;
import com.hejia.alauda.entity.Product;
import com.hejia.alauda.entity.Qualification;
import com.hejia.alauda.entity.ThirdOrder;
import com.hejia.alauda.entity.Traffic;
import com.hejia.alauda.entity.User;
import com.hejia.alauda.entity.example.AddressExample;
import com.hejia.alauda.entity.example.FinancingExample;
import com.hejia.alauda.entity.example.InvitationExample;
import com.hejia.alauda.entity.example.QualificationExample;
import com.hejia.alauda.event.EventConstant;
import com.hejia.alauda.event.MessageEvent;
import com.hejia.alauda.mongodb.KeyValue;
import com.hejia.alauda.persistence.mybatis.AddressMapper;
import com.hejia.alauda.persistence.mybatis.BonusRecordMapper;
import com.hejia.alauda.persistence.mybatis.FinancingMapper;
import com.hejia.alauda.persistence.mybatis.InvitationMapper;
import com.hejia.alauda.persistence.mybatis.ParameterMapper;
import com.hejia.alauda.persistence.mybatis.QualificationMapper;
import com.hejia.alauda.persistence.mybatis.ThirdOrderMapper;
import com.hejia.alauda.utils.ActivityUtils;
import com.hejia.alauda.utils.Encryption;
import com.hejia.alauda.utils.HttpRequest;
import com.hejia.alauda.utils.Pager;
import com.hejia.alauda.utils.RateUtil;
import com.hejia.alauda.utils.Utils;

@Service
public class ActivityServiceImpl implements ActivityService {

	protected final static Log logger = LogFactory.getLog(ActivityServiceImpl.class);

	@Value("#{settings['html5.domain']}")
	String mobileDomain;

	@Resource
	QualificationMapper qualificationMapper;

	@Resource
	FinancingMapper financingMapper;

	@Resource
	MessageService messageService;

	@Resource
	CommonService commonService;

	@Resource
	ConfigureService configureService;
	
	@Resource
	ParameterMapper parameterMapper;
	
	@Resource
	InvitationMapper invitationMapper;
	
	@Resource
	AddressMapper addressMapper;
	
	@Resource
	protected BalanceAndFinancingService balanceAndFinancingService;
	
	@Resource
	MongoTemplate mongoTemplate;
	
	@Resource
	UserService userService;
	
	@Resource
	BonusRecordMapper bonusRecordMapper;
	
	@Resource
	ThirdOrderMapper thirdOrderMapper;
	
	@Override
	public Award luckydrawForMarchTraffic2015(User user, boolean devMode) {
		synchronized (LOCK) {
			Calendar now = Calendar.getInstance();
			List<Award> pool = new ArrayList<Award>();
			QualificationExample qualificationExample = new QualificationExample();
			qualificationExample.appendCriterion("`awardCode`=", PHONE_CHARGE);
			qualificationExample.appendCriterion(String.format(MYSQL_DATE_FORMAT, "`createDate`") + "=",
					formatDate(now));
			qualificationExample.appendCriterion("`type`=", TYPE_MARCH_TRAFFIC_20150328);
			int count = qualificationMapper.countByExample(qualificationExample);

			int total = 0;
			int hour = now.get(Calendar.HOUR_OF_DAY);
			if (hour < 8) {
				total = 20;
			} else if (hour > 20) {
				total = 160;
			} else {
				total = 20 + (hour - 8 + 1) * 10;
			}
			// 实际剩余数量
			total -= count;
			logger.info(String.format("=======================>到%s为止还剩%s张20元话费奖品", formatDateTime(now), "" + total));
			if (total <= 0) {
				pool.add(CREDIT_2000);
			} else {
				// 查询中奖比率
				Parameter parameter = configureService.getParameter(Parameter.Category.Activity, "MarchTrafficRate");
				int rate = 15;
				if (parameter != null) {
					try {
						rate = parseNumber(trimToEmpty(parameter.getValue()), Integer.class);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				logger.info(String.format("=======================>抽奖比率为%s", rate + "%"));
				for (int i = 0; i < 100; i++)
					pool.add(i < rate ? PHONE_CHARGE : CREDIT_2000);
			}
			Random rnd = new Random();
			for (int i = 0; i < 30; i++)
				Collections.shuffle(pool, rnd);

			Award award = pool.size() <= 1 ? (pool.size() == 0 ? THANKS : pool.get(0)) : pool.get(rnd.nextInt(pool
					.size()));
			if (devMode) {
				// switch (award) {
				// case PHONE_CHARGE:
				// Qualification qualification = new Qualification();
				// qualification.setCreateDate(now.getTime());
				// qualification.setModifyDate(now.getTime());
				// qualification.setUser(user);
				// qualification.setAward(award.getName());
				// qualification.setAwardCode(award.getCode());
				// qualification.setType(TYPE_MARCH_TRAFFIC_20150328);
				// qualification.setUsed(Boolean.TRUE);
				// qualificationMapper.insert(qualification);
				// break;
				// default:
				// break;
				// }
			} else {
				Qualification qualification = new Qualification();
				qualification.setCreateDate(now.getTime());
				qualification.setModifyDate(now.getTime());
				qualification.setUser(user);
				qualification.setAward(award.getName());
				qualification.setAwardCode(award.getCode());
				qualification.setType(TYPE_MARCH_TRAFFIC_20150328);
				qualification.setUsed(Boolean.TRUE);
				qualificationMapper.insert(qualification);
			}
			return award;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean monitorTotalAmountForMarchTraffic2015() {
		Map<String, Object> params = new LinkedCaseInsensitiveMap<Object>();
		params.put("createDate", "2015-03");
		params.put("amount", 10000);

		// 从redis里获取已经发过消息的用户id
		List<Long> sended = (List<Long>) commonService.getOpsForValue(REDIS_KEY_SENDED_USER_ID + "MarchTraffic2015");
		// logger.info("===============>已经发送的用户ID：" + sended + "集合");
		if (!isEmpty(sended)) {
			params.put("user_ids", sended);
		}
		List<Long> list = financingMapper.monitorTotalAmountForMarchTraffic2015(params);
		if (!isEmpty(list)) {
			for (Long user_id : list) {
				logger.info("===============>用户ID：" + user_id + "发送消息");
				messageService.sendMessage(user_id, "欢乐合家手机流量派送中！", "又到月底了，潇洒了大半个月的流量又见底了>_<。一到月底流量就不够怎么破？欢乐合家流量加油站为你",
						mobileDomain + "/activity/sendflow/welcome.html");
				if (sended == null)
					sended = new ArrayList<Long>();
				sended.add(user_id);
				commonService.setOpsForValue(REDIS_KEY_SENDED_USER_ID + "MarchTraffic2015", sended,
						addHours(new Date(TIME_2015_04_01), 12));
			}
		}
		return true;
	}

	@Override
	@Deprecated
	public String findTrafficQualification(User user, Model model, boolean devMode) {
		Map<String, Object> params = new HashMap<String, Object>();

		params.put("userId", user.getId());
		params.put("amount", new BigDecimal(Traffic.QUALIFICATION.getCondition()));
		params.put("start", Traffic.getDate(Traffic.START_DATE));
		params.put("end", Traffic.getDate(Traffic.END_DATE));

		if (devMode) {
			params.put("start", Traffic.getDate(Traffic.DEV_START_DATE));
		}

		/* 判断是否抽奖条件 */
		boolean result = balanceAndFinancingService.findActivityIntervelAmounts(params);

		if (result) {
			return "EXCEPTION_0";
		} else {
			return "EXCEPTION_41000";
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, timeout = 3000)
	public Traffic traffic(User user) {
		Map<String, Object> params = new HashMap<>();

		Traffic tra = Traffic.THANKS;

		synchronized (LOCK) {
			params.put("type", TYPE_BONUS_20150415);
			params.put("date", new Date());
			params.put("used", true);

			byte number = qualificationMapper.findTrafficReslt(params);

			if (number < 30) {
				params.clear();
				params.put("type", TYPE_BONUS_20150415);
				params.put("used", true);
				params.put("userId", user.getId());

				number = qualificationMapper.findTrafficReslt(params);

				if (number == 0) {
					tra = Traffic.TRAFFIC;

					Qualification qualification = new Qualification();
					qualification.setCreateDate(Calendar.getInstance().getTime());
					qualification.setModifyDate(Calendar.getInstance().getTime());
					qualification.setUser(user);
					qualification.setAward(tra.getName());
					qualification.setAwardCode(tra.getCode());
					qualification.setType(TYPE_BONUS_20150415);
					qualification.setUsed(true);

					qualificationMapper.insert(qualification);

					messageService.sendMessage(user.getId(), "您成功获得20元流量礼包！",
							"好消息！您在抢流量活动中获得价值20元流量。流量将以话费形式在次日（节假日顺延）充入您的绑定手机。", null);
				} else {
					tra = Traffic.WINNER;
				}
			}
		}

		return tra;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public List<Map<String, String>> trafficWinners(String type, boolean used, boolean today) {
		Map<String, Object> params = new HashMap();

		params.put("type", type);
		params.put("used", used);
		params.put("today", today);

		List<Map<String, String>> result = qualificationMapper.trafficWinners(params);

		if (CollectionUtils.isEmpty(result))
			return Collections.EMPTY_LIST;

		String mobile;
		StringBuilder build = new StringBuilder();

		for (int i = 0; i < result.size(); i++) {
			mobile = result.get(i).get("mobile");
			build.append(mobile.substring(0, 3)).append("****").append(mobile.substring(7, 11));
			result.get(i).put("mobile", build.toString());
			build.delete(0, build.length());
		}

		return result;
	}

	@Override
	public void sweepstakesRecord(User user, String activityName, String activityType, String awardCode, Boolean used) {
		Date now = new Date();

		Qualification qual = new Qualification();

		qual.setAward(ActivityUtils.getName(activityName, awardCode));
		qual.setAwardCode(awardCode);
		qual.setCreateDate(now);
		qual.setModifyDate(now);
		qual.setUser(user);
		qual.setType(activityType);
		qual.setUsed(used);

		commonService.insertQualification(qual);
	}

	@Override
	public boolean activityAmountCheck(User user, String activityName,Boolean devMode) {
		Map<String, Object> params = this.activityCondition(user, activityName);

		return balanceAndFinancingService.findActivityIntervelAmounts(params);
	}

	@Override
	public boolean activitySingleCheck(User user, String activityName) {
		Map<String, Object> params = this.activityConditionBy51(user, activityName);
		
		String amount = ActivityUtils.getCondition(activityName, Activity.Raffle51.QUALIFICATION_TWO);
		params.put("amount", new BigDecimal(amount));
		return balanceAndFinancingService.findSingleAmountBy51(params);
	}

	private Map<String, Object> activityCondition(User user, String activityName) {
		Map<String, Object> params = new HashedMap<>();

		Date start;

		start = ActivityUtils.getDate(activityName, Activity.START_DATE);

		String amount = ActivityUtils.getCondition(activityName, Activity.QUALIFICATION);

		params.put("userId", user.getId());
		params.put("start", start);
		params.put("end", new Date());
		params.put("amount", new BigDecimal(amount));

		return params;
	}

	@Deprecated
	@Override
	public String activityFlagBy51(String activityName, Boolean devMode) {
			String now = formatDate(new Date());

			String start = ActivityUtils.getCondition(activityName, Activity.START_DATE);

			int interval = ActivityUtils.intervalDays(start, now);
			int actInter = Integer.valueOf(ActivityUtils.getCondition(activityName, Activity.INTERVAL));

			if (interval > actInter) {
				int multiple = interval / actInter;

				Calendar cal = Calendar.getInstance();
				cal.setTime(ActivityUtils.getDate(activityName, Activity.START_DATE));
				cal.add(Calendar.DAY_OF_WEEK, multiple * actInter);
				return formatDate(cal.getTime());
			} else {
				return ActivityUtils.getCondition(activityName, Activity.START_DATE);
			}
	}

	@Deprecated
	private Map<String, Object> activityConditionBy51(User user, String activityName) {
		Map<String, Object> params = new HashedMap<>();

		Date start;

		start = ActivityUtils.getDate(activityName, Activity.START_DATE);

		String now = formatDate(new Date());

		int interval = ActivityUtils.intervalDays(ActivityUtils.getCondition(activityName, Activity.START_DATE), now);
		int actInter = Integer.valueOf(ActivityUtils.getCondition(activityName, Activity.INTERVAL));

		if (interval > actInter) {
			int multiple = interval / actInter;

			Calendar cal = Calendar.getInstance();
			cal.setTime(ActivityUtils.getDate(activityName, Activity.START_DATE));
			cal.add(Calendar.DAY_OF_WEEK, multiple * actInter);

			start = cal.getTime();
		}
		
		params.put("userId", user.getId());
		params.put("start", start);
		params.put("end", new Date());

		return params;
	}

	@Override
	public boolean awardExpiryDate(String activityName) {
		String expiry = ActivityUtils.getCondition(activityName, Activity.EXPIRY_DATE);
		String desc = ActivityUtils.getDescription(activityName, Activity.EXPIRY_DATE);

		String end = ActivityUtils.getCondition(activityName, Activity.END_DATE);

		SimpleDateFormat mat = ActivityUtils.getDateFormat();

		Calendar cal = Calendar.getInstance();

		try {
			Date endTate = mat.parse(end);
			cal.setTime(endTate);
		} catch (ParseException e) {
			throw new IllegalArgumentException("配置文件时间格式错误", e);
		}

		return expriyDate(expiry, desc, cal);
	}
	
	@Override
	public boolean awardExpiryDate(String activityName, Date start) {
		String expiry = ActivityUtils.getCondition(activityName, Activity.EXPIRY_DATE);
		String desc = ActivityUtils.getDescription(activityName, Activity.EXPIRY_DATE);

		Calendar cal = Calendar.getInstance();
		cal.setTime(start);

		return expriyDate(expiry, desc, cal);
	}
	
	private boolean expriyDate(String expiry, String desc , Calendar cal) {
		int begin, last;
		begin = desc.indexOf("（");
		last = desc.indexOf("）");
		
		int inter = Integer.valueOf(expiry);

		if (begin != -1 && last != -1) {
			String unit = desc.substring(begin + 1, last);

			if (unit.equals("年")) {
				cal.add(Calendar.YEAR, inter);
			} else if (unit.equals("月")) {
				cal.add(Calendar.MONTH, inter);
			} else if (unit.equals("周")) {
				cal.add(Calendar.WEEK_OF_MONTH, inter);
			} else if (unit.equals("天")) {
				cal.add(Calendar.DAY_OF_WEEK, inter);
			} else if (unit.equals("时")) {
				cal.add(Calendar.HOUR_OF_DAY, inter);
			} else if (unit.equals("分")) {
				cal.add(Calendar.MINUTE, inter);
			} else if (unit.equals("秒")) {
				cal.add(Calendar.SECOND, inter);
			}

			Calendar now = Calendar.getInstance();

			if (now.compareTo(cal) > 0)
				return true;
			else
				return false;
		} else {
			return false;
		}
	}
	
	@Override
	public List<Map<String, String>> findQualifications(
			Map<String, Object> params) {
		return qualificationMapper.findQualifications(params);
	}

	@Override
	@Transactional(timeout = TransactionTimeout.THREE_SECOND)
	public String lotteryDraw(User user, String activityName, String activityType) {
		String award = Activity.Raffle51.CREDIT_2000;

		QualificationExample example = new QualificationExample();
		example.appendCriterion("type=", activityType);
		example.appendCriterion(String.format(MYSQL_DATE_FORMAT, "createDate") + "=", formatDate(new Date()));

		Calendar now = Calendar.getInstance();
		Calendar two = Calendar.getInstance();
		
		two.setTime(ActivityUtils.getDate(activityName, Activity.Raffle51.START_DATE_TWO));
		
		// 二期活动
		if (now.compareTo(two) == 1) 
			award = faffle51(user, example, activityName, award);
		else 
			award = faffle5Two(user, example, activityName, award);
			
		return award;
	}

	// 抽奖的具体实现
	@Deprecated
	private String faffle51(User user, QualificationExample example, String activityName, String award) {
		Random ran = new Random();
		int val = ran.nextInt(100) + 1;

		int todays;

		if (val <= 4) {
			// 足浴器
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.FOOT_BATH_EQUIPMENT);

			award = getAward(user, example, Activity.Raffle51.FOOT_BATH_EQUIPMENT, todays, activityName);
		} else if (val > 4 && val <= 24) {
			// 红枣
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.RED_JUJUBE);

			award = getAward(user, example, Activity.Raffle51.RED_JUJUBE, todays, activityName);
		} else if (val > 24 && val <= 44) {
			// 按摩锤
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.MASSAGE_HAMMER);

			award = getAward(user, example, Activity.Raffle51.MASSAGE_HAMMER, todays, activityName);
		} else if (val > 44 && val <= 56) {
			// 红包 30
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.CASH_30);

			award = getAwardCash(user, example, Activity.Raffle51.CASH_30, todays, activityName);
		} else {
			// 2000积分
			award = Activity.Raffle51.CREDIT_2000;

			sweepstakesRecord(user, activityName, Activity.Raffle51.TYPE, award, true);
		}
		
		if (award == Activity.Raffle51.CREDIT_2000) {
			String reides = ActivityUtils.getCondition(activityName, award);

			// 积分记录
			MessageEvent event = new MessageEvent(EventConstant.ACTIVITY_KEY_FLASH_SALE_BONUS, user);
			event.arg1 = Integer.valueOf(reides);

			CommonServiceImpl.applicationContext.publishEvent(event);
		}

		    return award;
	}
	
	// 抽奖的具体实现
	@Deprecated
	private String faffle5Two(User user, QualificationExample example, String activityName, String award) {
		Random ran = new Random();
		int val = ran.nextInt(1000) + 1;

		int todays;

		if (val <= 10) {
			// KINDLE
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.KINDLE);

			award = getAward(user, example, Activity.Raffle51.KINDLE, todays, activityName);
		} else if (val > 10 && val <= 30) {
			// JD_CARD_100
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.JD_CARD_100);

			award = getAward(user, example, Activity.Raffle51.JD_CARD_100, todays, activityName);
		} else if (val > 30 && val <= 60) {
			// CASH_50
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.CASH_50);

			award = getAwardCash(user, example, Activity.Raffle51.CASH_50, todays, activityName);
		} else if (val > 60 && val <= 94) {
			// CASH_20
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.CASH_20);

			award = getAwardCash(user, example, Activity.Raffle51.CASH_20, todays, activityName);
		} else if (val > 94 && val <= 274) {
			// LOCK_SPORTS_CUP
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.LOCK_SPORTS_CUP);

			award = getAward(user, example, Activity.Raffle51.LOCK_SPORTS_CUP, todays, activityName);
		} else if (val > 274 && val <= 454) {
			// HOLD_PILLOW
			todays = ActivityUtils.getTodayNumberByEachRound(activityName, Activity.Raffle51.HOLD_PILLOW);
			award = getAward(user, example, Activity.Raffle51.HOLD_PILLOW, todays, activityName);
		} else {
			// 2000积分
			award = Activity.Raffle51.CREDIT_2000;

			sweepstakesRecord(user, activityName, Activity.Raffle51.TYPE, award, true);
		}
		
		if (award == Activity.Raffle51.CREDIT_2000) {
			String reides = ActivityUtils.getCondition(activityName, award);

			// 积分记录
			MessageEvent event = new MessageEvent(EventConstant.ACTIVITY_KEY_FLASH_SALE_BONUS, user);
			event.arg1 = Integer.valueOf(reides);

			CommonServiceImpl.applicationContext.publishEvent(event);
		}

		return award;
	}
	
	// 对应当天活动有限制数量的，进行数量校验
	@Deprecated
	private String getAward(User user, QualificationExample example, String awardCode, int todays, String activityName) {
		String award = Activity.Raffle51.CREDIT_2000;

		if (todays > 0) {
			int count;
			boolean onlyOne = ActivityUtils.isOnlyOne(activityName, awardCode);
			boolean unexist = true;
			
			if (onlyOne) {
				QualificationExample qualExamplie = new QualificationExample();
				qualExamplie.appendCriterion("type = ", Activity.Raffle51.TYPE);
				qualExamplie.appendCriterion("user_id = ", user.getId());
				
				List<Qualification> quals = commonService.findQualificationsByExample(example);
				
				String code;
				
				for (Qualification qual : quals) {
					code = qual.getAwardCode();
					if(ActivityUtils.isEntity(activityName, code)) {
						unexist = false;
						break;
					}
				}
			}
			
			if (unexist) synchronized (LOCK) {

					example.appendCriterion("awardCode=", awardCode);
					count = qualificationMapper.countByExample(example);

					StringBuilder builder = new StringBuilder();
					String today = formatDate(new Date());
					String awardName = ActivityUtils.getName(activityName, awardCode);

					builder.append("活动奖品信息  编号： ").append(awardCode).append(" 名称").append(awardName).append(", ")
							.append(today).append("号，发放数量 ").append(todays).append("。已抽中数量 ");

					if (count < todays) {
						award = awardCode;
						sweepstakesRecord(user, activityName, Activity.Raffle51.TYPE, award, false);
						logger.info(builder.append(count + 1).toString());
					}
			} else {
				sweepstakesRecord(user, activityName, Activity.Raffle51.TYPE, award, true);
			}
		} else {
				sweepstakesRecord(user, activityName, Activity.Raffle51.TYPE, award, true);
		}

		return award;
	}

	// 对应当天活动有限制数量的，进行数量校验
	@Deprecated
	private String getAwardCash(User user, QualificationExample example, String awardCode, int todays,
			String activityName) {

		String award = Activity.Raffle51.CREDIT_2000;

		if (todays > 0) {
			synchronized (LOCK) {
				int count;
				example.appendCriterion("awardCode=", awardCode);
				count = qualificationMapper.countByExample(example);

				StringBuilder builder = new StringBuilder();
				String today = formatDate(new Date());
				String awardName = ActivityUtils.getName(activityName, awardCode);

				builder.append("活动奖品信息  编号： ").append(awardCode).append(" 名称").append(awardName).append(", ")
						.append(today).append("号，发放数量 ").append(todays).append("。已抽中数量 ");

				if (count < todays) {
					award = awardCode;
					sweepstakesRecord(user, activityName, Activity.Raffle51.TYPE, award, true);

					// 红包记录
					MessageEvent event = new MessageEvent(EventConstant.ACTIVITY_KEY_ADD_BONUS_RECEIVE_EVENT, user);
					event.arg1 = 30;

					CommonServiceImpl.applicationContext.publishEvent(event);

					logger.info(builder.append(count + 1).toString());
				} else {
					sweepstakesRecord(user, activityName, Activity.Raffle51.TYPE, award, true);
				}
			}
		} else {
				sweepstakesRecord(user, activityName, Activity.Raffle51.TYPE, award, true);
		}

		return award;
	}

	@Override
	public void calculateHushen300Income() {
		logger.info("================>计算股神红包开始");
		Date now = new Date();
		String nowStr = formatDate(now);
		BigDecimal standard_deviation = new BigDecimal("0");
		Object v = commonService.getMongodbForValue(MONGODB_KEY_HUSHEN_300_CALCULATE_DATE + nowStr);
		if(v == null){
			//先锁定业务 只允许业务上单线程操作 synchronized关键字无法保证整体锁定 所以只能依靠乐观锁
			if(parameterMapper.lockConfig("1", "0", Parameter.Category.Custom.toString(), "HUSHEN_300_CONFIG_LOCK")>0){
				logger.info("================>计算股神红包");
				commonService.setMongodbForValue(MONGODB_KEY_HUSHEN_300_CALCULATE_DATE + nowStr, nowStr);
				//读取配置 json格式
				Parameter parameter = configureService.getParameter(Parameter.Category.Custom, "HUSHEN_300_CONFIG");
				if(parameter!=null){
					JSONArray array = (JSONArray) JSONArray.parse(parameter.getValue());
					for (int i = 0; i < array.size(); i++) {
						JSONObject item = array.getJSONObject(i);
						/*一个周期的清算时间，周期结束时间，周期开始时间*/
						String cleardate = item.getString("ClearDate"), weekEndDate = item.getString("WeekEndDate"), weekStartDate = item.getString("WeekStartDate");
						/*weekStartIndex周期开始沪深300指数 weekEndIndex周期结束沪深300指数*/
						BigDecimal weekStartIndex = new BigDecimal(item.getString("WeekStartIndex")), weekEndIndex = new BigDecimal(item.getString("WeekEndIndex"));
						//判断今天是否是结算日
						if(nowStr.equals(cleardate)){
							//判断指数是否有上涨
							if(weekEndIndex.subtract(weekStartIndex).compareTo(standard_deviation)>0){
								
								BigDecimal rate = RateUtil.getStockIncrease(weekStartIndex,weekEndIndex);
								//找出结算日之前的产生特权的用户
								List<KeyValue> list = mongoTemplate.find(new Query(new Criteria("value").lt(nowStr).and("key").regex(MONGODB_KEY_USER_HUSHEN_300_DATE + item.getString("WeekStartDate") + "_" + item.getString("WeekEndDate") + "_")), KeyValue.class);
								for(KeyValue data:list){
									//找出有特权的用户id
									Long user_id = new Long(substring(data.getKey(), lastIndexOf(data.getKey(), "_") + 1));
									//用户实际开始计算日期
//									String userStartDate = data.getValue().toString().compareTo(weekStartDate)>=0 ? data.getValue().toString() : weekStartDate;
									//查询用户下的所有资产
									FinancingExample financingExample = new FinancingExample();
									//financingExample.appendCriterion(String.format(MYSQL_DATE_FORMAT, "SUBDATE(`settlementDate`,INTERVAL 1 DAY)") + ">=", getMaxDateStr(data.getValue().toString(), weekStartDate));
									//financingExample.appendCriterion("NOT " + String.format(MYSQL_DATE_FORMAT, "`valueDate`") + ">", item.getString("WeekEndDate"));
									financingExample.appendCriterion(String.format(MYSQL_DATE_FORMAT, "createDate")+"<=", weekEndDate);
									financingExample.appendCriterion("`createDate`>=", data.getValue());
									financingExample.appendCriterion("`user_id`=", user_id);
									List<Financing> financings = financingMapper.selectByExample(financingExample, null);
									BigDecimal thisIncome = new BigDecimal("0");
									for(Financing financing:financings){
										//用户实际开始计算日期取大者 先比较计息日和上周开始时间
										String userStartDate = getMaxDateStr(
												formatDate(financing
														.getCreateDate()),
												weekStartDate);
										//比较结束时间 资产结息日和结算周期结束时间按比较 取较小者
										String userEndDate = getMinDateStr(
												weekEndDate,
												formatDate(financing
														.getExpiredDate()));
										//计算之间总共有多少天
										int days = commonService.caculateDateInterval(userEndDate, userStartDate) + 1;
										logger.info("days:" + days);
										if(days >= 1){
											BigDecimal income = new BigDecimal(financing.getAmount()
													.doubleValue()
													* rate.doubleValue()
													/ 360
													* days).setScale(2, RoundingMode.UP);
											thisIncome = thisIncome.add(income);
											
//											List<String> financing_records = (List<String>)commonService.getMongodbForValue(MONGODB_KEY_USER_HUSHEN_300_FINANCING_RECORD + user_id + "_" + financing.getId());
//											if(financing_records==null){
//												financing_records = new LinkedList<String>();
//											}
//											financing_records.add(nowStr + "_" + income);
											commonService.setMongodbForValue(MONGODB_KEY_USER_HUSHEN_300_FINANCING_RECORD + user_id + "_" + financing.getId(), income);
											logger.info("income:" + income);
											logger.info("id:"+financing.getId());
											logger.info("userStartDate:"+userStartDate);
											logger.info("userEndDate:"+userEndDate);
											logger.info("amount:"+financing.getAmount());
											logger.info("days:"+days);
										}
									}
									commonService.setMongodbForValue(MONGODB_KEY_USER_HUSHEN_300_INCOME + item.getString("WeekStartDate") + "_" + item.getString("WeekEndDate") + "_" + user_id, thisIncome.toString());
									//记录用户收益履历
//									List<String> records = (List<String>) commonService.getMongodbForValue(MONGODB_KEY_USER_HUSHEN_300_INCOME_RECORD + user_id);
//									if(records==null){
//										records = new LinkedList<String>();
//									}
//									records.add(thisIncome.toString());
//									commonService.setMongodbForValue(MONGODB_KEY_USER_HUSHEN_300_INCOME_RECORD + user_id, records);
									//看收益是否大于0
									if(thisIncome.compareTo(standard_deviation)>0){
										//下面是发送红包的功能
										BonusRecord record = new BonusRecord();
										record.setAmount(thisIncome);
										record.setDescription("您的股神特权红包已发放至您的合家账户，请尽快使用哦。");
										record.setType("STOCK_HUSHEN300");
										record.setCode("STOCK_HUSHEN300");
										record.setConsume(false);
										record.setUser(userService.findUserById(user_id));
										record.setRemaining(record.getAmount());
										record.setCreateDate(Calendar.getInstance().getTime());
										record.setModifyDate(record.getCreateDate());
										record.setExpiredDate(DateUtils.addDays(record.getCreateDate(), 30));
										bonusRecordMapper.insert(record);
										messageService.sendMessage(user_id, "股神特权红包发放", "您的股神特权红包已发放至您的合家账户，请尽快使用哦。", null);
									}
								}
							}
							break;
						}
					}
				}
				parameterMapper.lockConfig("0", "1", Parameter.Category.Custom.toString(), "HUSHEN_300_CONFIG_LOCK");
			}
		}
		logger.info("================>计算股神红包结束");
	}

	@Override
	public String getMinHushen300AuthorizeTime(Long id) {
		Parameter parameter = configureService.getParameter(Parameter.Category.Custom, "HUSHEN_300_CONFIG");
		List<Map<String,Object>> configs = (List<Map<String,Object>>) readValue(parameter.getValue(), List.class);
		for(Map<String,Object> item : configs){
			String weekStartDate = (String) item.get("WeekStartDate"), weekEndDate = (String) item
					.get("WeekEndDate");
			String time = (String) commonService
					.getMongodbForValue(MONGODB_KEY_USER_HUSHEN_300_DATE
							+ weekStartDate + "_"
							+ weekEndDate + "_" + id);
			if(isNotBlank(time)){
				return time;
			}
		}
		return "";
	}

	@Override
	public List<String> getChildrensDay2015Config() {
		Object value = commonService.getOpsForValue(REDIS_KEY_CHILDRENS_DAY_2015_CONFIG);
		if(value==null){
			Parameter parameter = configureService.getParameter(Parameter.Category.Custom, "2015_CHILDREN'S_DAY_CONFIG");
			Map<String, Object> config = readValue(parameter.getValue());
			value = (List<String>) config.get("dates");
			commonService.setOpsForValue(REDIS_KEY_CHILDRENS_DAY_2015_CONFIG, value, addSeconds(new Date(), 30));
		}
		return (List<String>) value;
	}

	@Override
	public JSONObject getYiche2015Config() {
//		Object value = commonService.getOpsForValue(REDIS_KEY_YICHE_2015_CONFIG);
//		if(value==null){
//			Parameter parameter = configureService.getParameter(Parameter.Category.Custom, "2015_YICHE_CONFIG");
//			value = JSONObject.parseObject(parameter.getValue());
//			commonService.setOpsForValue(REDIS_KEY_YICHE_2015_CONFIG, value, addSeconds(new Date(), 60));
//		}
//		return (JSONObject) value;
		Parameter parameter = configureService.getParameter(Parameter.Category.Custom, "2015_YICHE_CONFIG");
		return JSONObject.parseObject(parameter.getValue());
	}

	@Override
	public int findQualificationCountByExample(QualificationExample example) {
		return this.qualificationMapper.countByExample(example);
	}

	@Override
	public boolean isYiche2015Expired() {
		String now = formatDateTime(new Date());
		JSONObject config = getYiche2015Config();
		String startDate = config.getString("startDate"),endDate = config.getString("endDate");
		return !(now.compareTo(startDate)>=0 && now.compareTo(endDate)<=0);
	}

	@Override
	public boolean isRegisterInYiche2015(Date register) {
		String registerDate = formatDateTime(register);
		JSONObject config = getYiche2015Config();
		String startDate = config.getString("startDate"),endDate = config.getString("endDate");
		return registerDate.compareTo(startDate)>=0 && registerDate.compareTo(endDate)<=0;
	}

	@Override
	public List<KeyValue> findYoukuInvitionByUser(Long id,int limit) {
		Criteria criteria = new Criteria("key").regex(MONGODB_KEY_USER_YOUKU_INVITE + id + "_");
		Query query = new Query(criteria).with(new Sort(Direction.DESC, "createDate")).limit(limit);
		return mongoTemplate.find(query, KeyValue.class);
	}

	@Override
	public int updateQualificationThroughJiayuan(Map<String, Object> params) {
		return qualificationMapper.updateQualificationThroughJiayuan(params);
	}

	@Override
	public int insertThirdOrder(ThirdOrder record) {
		return thirdOrderMapper.insert(record);
	}

	@Override
	public ThirdOrder findOneThirdOrder(Long id) {
		return thirdOrderMapper.selectByPrimaryKey(id);
	}

	@Override
	public int updateThirdOrder(ThirdOrder record) {
		return thirdOrderMapper.updateByPrimaryKey(record);
	}

	@Override
	public BigDecimal calculateMagpieFestivalTotalAmout(User user) {
		BigDecimal amount = new BigDecimal(0);
		if(user!=null){
			List<Financing> list = findMagpieFestivalFinancings(user);
			if(!isEmpty(list)){
				for(Financing item:list){
					amount = amount.add(item.getAmount());
				}
			}
		}
		return amount;
	}

	@Override
	public List<Financing> findMagpieFestivalFinancings(User user) {
		if(user!=null){
			final Method method = findMethod(OrderSerial.class, "getSerial");
			List<OrderSerial> orderSerials = mongoTemplate.find(new Query(new Criteria("track_id").is(EventConstant.TRACK_HJ_MM_MAGPIE_FESTIVAL)), OrderSerial.class);
			if(!isEmpty(orderSerials)){
				
				JSONObject config = new JSONObject(configureService.getActivityConfig("2015_MAGPIE_FESTIVAL_CONFIG"));
				
				FinancingExample example = new FinancingExample();
				example.appendCriterion("order_id IN (SELECT id FROM `order` WHERE " + collectionToDelimitedString(new DataHandler(orderSerials).convert(new RowMapper() {
					@Override
					public Object mapRow(Object rs, int rowNum) {
						return "`orderNumber`=\'" + invokeMethod(method, rs) + "\'";
					}
				}), " OR ") + ")");
				example.appendCriterion("date(`createDate`)<=", config.getString("Deadline"));
				example.appendCriterion("date(`createDate`)>=", config.getString("StartDate"));
				example.appendCriterion("`user_id`=", user.getId());
				return this.financingMapper.selectByExample(example, null);
			}
		}
		return Collections.EMPTY_LIST;
	}

	@Override
	public void dealCrab2015(Financing financing) {
		//读取配置
		JSONObject config = new JSONObject(configureService.getActivityConfig("2015_NATIONAL_DAY_CONFIG"));
		//截止日
		String deadline = config.getString("deadline"), crab_deadline = config.getString("crab_deadline"), iphone_deadline = config.getString("iphone_deadline");
		String buyTime = formatDate(financing.getOrder().getCreateDate());
		
		//查询购买渠道
		OrderSerial orderSerial = mongoTemplate.findOne(new Query(new Criteria("serial").is(financing.getOrder().getOrderNumber())), OrderSerial.class);
		if(orderSerial!=null){
			if(EventConstant.TRACK_HJ_MM_NATIONAL_DAY_2015_1.equalsIgnoreCase(orderSerial.getTrack_id())){
				if(buyTime.compareTo(crab_deadline)<=0){
					if(Product.Category.QUARTER.equals(financing.getProduct().getCategory())
							||(Product.Category.HALF_A_YEAR.equals(financing.getProduct().getCategory()) && financing.getInterestRate().compareTo(new BigDecimal("0.11"))<=0)
							||(Product.Category.YEAR.equals(financing.getProduct().getCategory()) && financing.getInterestRate().compareTo(new BigDecimal("0.12"))<=0)){
						Integer amount = (Integer) commonService.getMongodbForValue(EventConstant.MONGODB_KEY_USER_NATIONAL_DAY_2015_AMOUNT + financing.getUser().getId());
						if(amount==null)
							amount = 0;
						amount += financing.getAmount().intValue();
						commonService.setMongodbForValue(EventConstant.MONGODB_KEY_USER_NATIONAL_DAY_2015_AMOUNT + financing.getUser().getId(), amount);
					}
				}
			} else if(EventConstant.TRACK_HJ_MM_NATIONAL_DAY_2015_2.equalsIgnoreCase(orderSerial.getTrack_id())){
				if(buyTime.compareTo(iphone_deadline)<=0){
					if(Product.Category.YEAR.equals(financing.getProduct().getCategory()) && financing.getInterestRate().compareTo(new BigDecimal("0.12"))<=0){
						Integer amount = (Integer) commonService.getMongodbForValue(EventConstant.MONGODB_KEY_USER_NATIONAL_DAY_2015_AMOUNT_YEAR_POOL + financing.getUser().getId());
						if(amount==null)
							amount = 0;
						amount += financing.getAmount().intValue();
						commonService.setMongodbForValue(EventConstant.MONGODB_KEY_USER_NATIONAL_DAY_2015_AMOUNT_YEAR_POOL + financing.getUser().getId(), amount);
					}
				}
			}
		}
	}

	@Override
	public void dealZeroYuanBusiness(Financing financing) {
		if(Product.Category.YEAR.equals(financing.getProduct().getCategory())){
			BigDecimal s1 = new BigDecimal("0"), s2 = new BigDecimal("0.05");
			String track_id = trimToEmpty(financing.getTrack());
			String[] tracks = new String[]{TRACK_HJ_MM_ZERO_YUAN_PHILIPS_TACHOGRAPH,TRACK_HJ_MM_ZERO_YUAN_APPLE_WATCH,TRACK_HJ_MM_ZERO_YUAN_IPHONE_6S_16G};
			for(String t : tracks){
				if(track_id.equals(t)){
					if(s1.compareTo(financing.getInterestRate())>=0){
						fillZeroYuanPool(financing, t, 0);
						fillZeroYuanPoolShow(financing, t, 0);
					} else if(s2.compareTo(financing.getInterestRate())>=0){
						fillZeroYuanPool(financing, t, 5);
						fillZeroYuanPoolShow(financing, t, 5);
					}
				}
			}
		}
	}
	
	private void fillZeroYuanPool(Financing financing, String track_id, int mark){
		String key = String.format(MONGODB_KEY_USER_ZERO_YUAN, financing.getUser().getId(), track_id, mark);
		Integer amount = (Integer) commonService.getMongodbForValue(key);
		if (amount == null)
			amount = 0;
		amount += financing.getAmount().intValue();
		
		JSONObject obj = new JSONObject(configureService.getActivityConfig("ZERO_YUAN_BUSINESS_RULE_CONFIG"));
		JSONArray list = obj.getJSONArray("list");
		for(int i=0;i<list.size();i++){
			JSONObject item = list.getJSONObject(i);
			if(item.getString("track_id").equals(track_id)){
				boolean isAdd = true;
				if(i == 0){
					QualificationExample qualificationExample = new QualificationExample();
					qualificationExample.appendCriterion("`awardCode`=", item.getString("name"));
					qualificationExample.appendCriterion("`user_id`=", financing.getUser().getId());
					qualificationExample.appendCriterion("`type`=", Qualification.TYPE_ZERO_YUAN_BUSINESS_2015);
					isAdd = findQualificationCountByExample(qualificationExample)<=0;
				}
				if(isAdd){
					int number = amount/item.getIntValue(mark + "");
					if(number>0){
						number = i == 0 ? 1 : number;
						//先判断是否还有库存
						QualificationExample qualificationExample = new QualificationExample();
						qualificationExample.appendCriterion("`awardCode`=", item.getString("name"));
						qualificationExample.appendCriterion("`type`=", Qualification.TYPE_ZERO_YUAN_BUSINESS_2015);
						if(findQualificationCountByExample(qualificationExample)<item.getIntValue("number")){
							for(int k=0;k<number;k++){
								Qualification qualification = new Qualification();
						    	qualification.setCreateDate(new Date());
						    	qualification.setModifyDate(qualification.getCreateDate());
						    	qualification.setUser(financing.getUser());
						    	qualification.setUsed(false);
						    	qualification.setAward(item.getString("name"));
						    	qualification.setAwardCode(item.getString("name"));
						    	qualification.setType(Qualification.TYPE_ZERO_YUAN_BUSINESS_2015);
						    	commonService.insertQualification(qualification);
						    	amount = amount - item.getIntValue(mark + "");
							}
						}
					}
				}
			}
		}
		commonService.setMongodbForValue(key, amount);
	}
	
	private void fillZeroYuanPoolShow(Financing financing, String track_id, int mark){
		String key = String.format(MONGODB_KEY_USER_ZERO_YUAN_SHOW, financing.getUser().getId(), track_id, mark);
		Integer amount = (Integer) commonService.getMongodbForValue(key);
		if (amount == null)
			amount = 0;
		amount += financing.getAmount().intValue();
		commonService.setMongodbForValue(key, amount);
	}

	@Override
	public void dealJiayuanSeasonFiveBusiness(Financing financing) {
		if (Product.Category.YEAR.equals(financing.getProduct().getCategory())) {
			if (EventConstant.TRACK_HJ_MM_JIAYUAN_FIVE_SEASON
					.equalsIgnoreCase(trimToEmpty(financing.getTrack()))) {
				JSONObject config = getActivityConfig("2015_JIAYUAN_CONFIG_S5");
				JSONArray base = config.getJSONObject("config").getJSONArray("base");
				JSONObject product = null;
				for(int i=0;i<base.size();i++){
					JSONObject item = base.getJSONObject(i);
					if (new BigDecimal(item.getString("rate"))
							.compareTo(financing.getInterestRate()) == 0) {
						product = item;
					}
				}
				if(product!=null){
					String key = EventConstant.TRACK_HJ_MM_JIAYUAN_FIVE_SEASON + "_"
							+ financing.getUser().getId() + "_" + product.getString("mark");
					Integer amount = (Integer) commonService
							.getMongodbForValue(key);
					if (amount == null)
						amount = 0;
					amount += financing.getAmount().intValue();
					commonService.setMongodbForValue(key, amount);
					if(amount/product.getIntValue("min_amount")>0){
						QualificationExample qualificationExample = new QualificationExample();
						qualificationExample.appendCriterion("`user_id`=", financing.getUser().getId());
						qualificationExample.appendCriterion("`type`=", Qualification.TYPE_JIAYUAN_S5);
						if(findQualificationCountByExample(qualificationExample)==0){
							Qualification qualification = new Qualification();
					    	qualification.setCreateDate(new Date());
					    	qualification.setModifyDate(qualification.getCreateDate());
					    	qualification.setUser(financing.getUser());
					    	qualification.setUsed(false);
					    	qualification.setAward("iPhone6s 64GB");
					    	qualification.setAwardCode("iPhone6s 64GB");
					    	qualification.setType(Qualification.TYPE_JIAYUAN_S5);
					    	commonService.insertQualification(qualification);
						}
					}
				}
			}
		}
	}

	@Override
	public JSONObject getActivityConfig(String key) {
		// 读入配置
		Object config = commonService.getOpsForValue("Redis_Activity_Config_"
				+ key);
		if (config == null) {
			config = new JSONObject(configureService.getActivityConfig(key));
			commonService.setOpsForValue("Redis_Activity_Config_" + key,
					config, addMinutes(new Date(), 5));
		}
		return (JSONObject) config;
	}

	@Override
	public void dealDoubleElevenBusiness(Financing financing) {
		JSONObject config = getActivityConfig("2015_HEJIA_ONEYEAR_ACTIVITY_CONFIG").getJSONObject("double-eleven-config");
		String date = config.getString("date"), createDate = formatDate(financing.getCreateDate());
		if(date.equals(createDate)){
			int times = config.getIntValue("times");
			BigDecimal amount = new BigDecimal(0);
			switch (financing.getProduct().getCategory()) {
			case CURRENT:
				amount = new BigDecimal(financing.getAmount().doubleValue()
						* financing.getStageInterestRate().doubleValue() / 360
						* times).setScale(2, RoundingMode.UP);
				break;
			default:
				amount = new BigDecimal(financing.getAmount().doubleValue()
						* financing.getInterestRate().doubleValue() / 360
						* times).setScale(2, RoundingMode.UP);
				break;
			}
			if(amount.doubleValue()>0){
				BonusRecord record = new BonusRecord();
				record.setCreateDate(new Date());
				record.setModifyDate(record.getCreateDate());
				record.setAmount(amount);
				record.setExpiredDate(addDays(record.getCreateDate(), config.getIntValue("active-time")-1));
				record.setDescription("2015年双11收益翻倍红包");
				record.setType("HEJIA_DOUBLE_ELEVEN");
				record.setCode("HEJIA_DOUBLE_ELEVEN");
				record.setConsume(false);
				record.setUser(financing.getUser());
				record.setRemaining(record.getAmount());
				bonusRecordMapper.insert(record);
			}
		}
	}

	@Override
	public void handleBaiheBusiness(Financing financing) {
		if("hejia_baihe".equalsIgnoreCase(financing.getProduct().getChannel())){
			//判断是否领取过
			QualificationExample qualificationExample = new QualificationExample();
			qualificationExample.appendCriterion("`type`=", TYPE_ZERO_BAIHE_GIFT_SEASON_1);
			qualificationExample.appendCriterion("`user_id`=", financing.getUser().getId());
			if(findQualificationCountByExample(qualificationExample)==0 && isNoneBlank(financing.getUser().getOpenId())){
				List<NameValuePair> parameters = new ArrayList<NameValuePair>();
				parameters.add(new BasicNameValuePair("userId", financing.getUser().getOpenId()));
				parameters.add(new BasicNameValuePair("userName", financing.getUser().getRealName()));
				parameters.add(new BasicNameValuePair("userMobile", financing.getUser().getMobile()));
				parameters.add(new BasicNameValuePair("amount", financing.getAmount().intValue() + ""));
				parameters.add(new BasicNameValuePair("createDate", financing.getCreateDate().getTime()/1000+""));
				parameters.add(new BasicNameValuePair("activityType", "hd20151029"));
				parameters.add(new BasicNameValuePair("name", financing.getProduct().getName()));
				parameters.add(new BasicNameValuePair("orderNumber", financing.getOrder().getOrderNumber()));
				parameters.add(new BasicNameValuePair("sign", Encryption.getMD5("e02bde5fedef350e" + financing.getOrder().getOrderNumber())));
//				parameters.add(new BasicNameValuePair("sign", "e02bde5fedef350e"));
				StringBuilder sb = new StringBuilder();
				for(NameValuePair p : parameters){
					BasicNameValuePair b = (BasicNameValuePair) p;
					sb.append("&").append(p.getName()).append("=").append(p.getValue());
				}
				logger.info("==================>百合回调参数：" + sb.toString());
				//211.151.69.126
				final String result = HttpRequest.executePost("http://xact.baihe.com/Lovebankcallback/HjChargeCenter", parameters, null);
				if(isNoneBlank(result)){
					final Map<String,Object> callback = Utils.readValue(result);
					logger.info("==================>百合回调结果：" + callback);
					logger.info("==================>百合回调结果：" + callback.get("code").getClass().getName());
					Integer code = (Integer)callback.get("code");
					if (null != code && 200 == code.intValue()) {
						ThirdOrder thirdOrder = new ThirdOrder();
						thirdOrder.setCreateDate(new Date());
						thirdOrder.setModifyDate(financing.getCreateDate());
						thirdOrder.setUser(financing.getUser());
						thirdOrder.setPid(null);
						thirdOrder.setUid(financing.getUser().getOpenId());
						thirdOrder.setPlatform(ThirdOrder.PLATFORM_BAIHE);
						thirdOrder.setStatus(callback.get("code") + "_" + callback.get("msg"));
						thirdOrder.setOrderNumber(financing.getOrder().getOrderNumber());
						insertThirdOrder(thirdOrder);
						
						Qualification qualification = new Qualification();
				    	qualification.setCreateDate(new Date());
				    	qualification.setModifyDate(qualification.getCreateDate());
				    	qualification.setUser(financing.getUser());
				    	qualification.setUsed(true);
				    	qualification.setAward("百合水晶会员");
				    	qualification.setAwardCode("百合水晶会员");
				    	qualification.setType(Qualification.TYPE_ZERO_BAIHE_GIFT_SEASON_1);
				    	commonService.insertQualification(qualification);
					}
				}
			}
		}
	}

	@Override
	public KeyValue findGroupBuyingMember(String track, User user, Long founder) {
		track = trimToEmpty(track.toUpperCase());
		KeyValue kv = null;
		if(null!=user){
			List<KeyValue> list = mongoTemplate.find(
					new Query(new Criteria("key")
							.regex(MONGODB_KEY_GROUP_BUYING_FOUNDER + "_"
									+ track)), KeyValue.class);
			if(!isEmpty(list)){
				for(KeyValue item:list){
					List<Long> members = (List<Long>) item.getValue();
					if(members.contains(user.getId())){
						kv = item;
						break;
					}
				}
			}
			if(null == kv){
				if(null != founder){
					list = mongoTemplate.find(
							new Query(new Criteria("key")
									.is(MONGODB_KEY_GROUP_BUYING_FOUNDER + "_"
											+ track + "_" + founder)), KeyValue.class);
					if(!isEmpty(list)){
						kv = list.get(0);
					}
				}
			}
		}
		return kv;
	}

	@Override
	public void handleGroupBuyingBusiness(Financing financing) {
		if(Product.Category.YEAR.equals(financing.getProduct().getCategory())){
			String track = trimToEmpty(financing.getTrack());
			JSONObject config = getActivityConfig("2015_HEJIA_ONEYEAR_ACTIVITY_CONFIG").getJSONObject("group-buying-config");
			int max_people = config.getIntValue("max_people");
			if (TRACK_HJ_MM_GROUP_BUYING_PAN.equals(track)
					|| TRACK_HJ_MM_GROUP_BUYING_IPHONE6S.equals(track)) {
				if(TRACK_HJ_MM_GROUP_BUYING_PAN.equals(track))
					config = config.getJSONObject("buy-together-bebungled");
				else
					config = config.getJSONObject("buy-together-iphone6s");
				int minAmount = config.getIntValue("amount");
				Integer totalAmount = (Integer) commonService.getMongodbForValue(track + "_amount_" + financing.getUser().getId());
				if(null == totalAmount)
					totalAmount = 0;
				totalAmount += financing.getAmount().intValue();
				commonService.setMongodbForValue(track + "_amount_" + financing.getUser().getId(), totalAmount);
				List<Long> founders = (List<Long>) commonService
						.getMongodbForValue(MONGODB_KEY_GROUP_BUYING_FOUNDER + "_"
								+ track.toUpperCase() + "_"
								+ financing.getUser().getExternal());
				if(null==founders)
					founders = new ArrayList<Long>();
				if(!founders.contains(financing.getUser().getId()))
					founders.add(financing.getUser().getId());
				commonService.setMongodbForValue(MONGODB_KEY_GROUP_BUYING_FOUNDER
						+ "_" + track.toUpperCase() + "_"
						+ financing.getUser().getExternal(), founders);
				if(totalAmount>=minAmount){
					List<Long> queue = (List<Long>) commonService
							.getMongodbForValue(MONGODB_KEY_GROUP_BUYING_QUEUE
									+ "_" + track.toUpperCase() + "_"
									+ financing.getUser().getExternal());
					if (null == queue)
						queue = new ArrayList<Long>();
					if (!queue.contains(financing.getUser().getId()))
						if (queue.size() < max_people)
							queue.add(financing.getUser().getId());
					commonService.setMongodbForValue(MONGODB_KEY_GROUP_BUYING_QUEUE
							+ "_" + track.toUpperCase() + "_"
							+ financing.getUser().getExternal(), queue);
				}
			} else if (-1 != indexOf(track, TRACK_HJ_MM_GROUP_BUYING_SHARE_IPHONE6S)
					|| -1 != indexOf(track, TRACK_HJ_MM_GROUP_BUYING_SHARE_PAN)) {
				if(-1 != indexOf(track, TRACK_HJ_MM_GROUP_BUYING_SHARE_PAN))
					config = config.getJSONObject("buy-together-bebungled");
				else
					config = config.getJSONObject("buy-together-iphone6s");
				Long external = new Long(substring(track, lastIndexOf(track, "_")+1));
				
				track = config.getString("track");
				
				int minAmount = config.getIntValue("amount");
				Integer totalAmount = (Integer) commonService.getMongodbForValue(track + "_amount_" + financing.getUser().getId());
				if(null == totalAmount)
					totalAmount = 0;
				totalAmount += financing.getAmount().intValue();
				commonService.setMongodbForValue(track + "_amount_" + financing.getUser().getId(), totalAmount);
				
				List<Long> founders = (List<Long>) commonService
						.getMongodbForValue(MONGODB_KEY_GROUP_BUYING_FOUNDER + "_"
								+ track.toUpperCase() + "_"
								+ external);
				if(null==founders)
					founders = new ArrayList<Long>();
				if(!founders.contains(financing.getUser().getId()))
					founders.add(financing.getUser().getId());
				commonService.setMongodbForValue(MONGODB_KEY_GROUP_BUYING_FOUNDER
						+ "_" + track.toUpperCase() + "_"
						+ external, founders);
				if(totalAmount>=minAmount){
					List<Long> queue = (List<Long>) commonService
							.getMongodbForValue(MONGODB_KEY_GROUP_BUYING_QUEUE
									+ "_" + track.toUpperCase() + "_"
									+ external);
					if (null == queue)
						queue = new ArrayList<Long>();
					if (!queue.contains(financing.getUser().getId()))
						if (queue.size() < max_people)
							queue.add(financing.getUser().getId());
					commonService.setMongodbForValue(MONGODB_KEY_GROUP_BUYING_QUEUE
							+ "_" + track.toUpperCase() + "_"
							+ external, queue);
				}
			}
		}
	}

	@Override
	public void handleBaiheOtherBusiness(Financing financing) {
		boolean needBaiheCallback = false;
		List<String> list = (List<String>) commonService.getMongodbForValue("Baihe_Employee_Mobile_Number");
		//如果是百合注册的就认为需要返回
		if("baihe".equalsIgnoreCase(financing.getUser().getReferee())){
			needBaiheCallback = true;
		}else if(list.contains(financing.getUser().getMobile())){//如果是百合的种子用户就认为需要返回
			needBaiheCallback = true;
		} else {
			InvitationExample example = new InvitationExample();
			example.appendCriterion("`invitee_id`=", financing.getUser().getId());
			Invitation invitation = this.invitationMapper.selectOneByExample(example);
			if(null != invitation){
				if(list.contains(invitation.getInviter().getMobile())){
					needBaiheCallback = true;
				}
			}
		}
		if(needBaiheCallback){
			List<NameValuePair> parameters = new ArrayList<NameValuePair>();
			parameters.add(new BasicNameValuePair("userId",isNoneBlank(financing.getUser().getOpenId())?financing.getUser().getOpenId():"0"));
			parameters.add(new BasicNameValuePair("userName",financing.getUser().getRealName()));
			parameters.add(new BasicNameValuePair("userMobile",financing.getUser().getMobile()));
			parameters.add(new BasicNameValuePair("amount",financing.getAmount().intValue() + ""));
			parameters.add(new BasicNameValuePair("createDate",financing.getCreateDate().getTime()/ 1000 + ""));
			parameters.add(new BasicNameValuePair("activityType", "0"));
			parameters.add(new BasicNameValuePair("name", financing.getProduct().getName()));
			parameters.add(new BasicNameValuePair("orderNumber", financing.getOrder().getOrderNumber()));
			parameters.add(new BasicNameValuePair("sign",Encryption.getMD5("e02bde5fedef350e"+ financing.getOrder().getOrderNumber())));
			
			StringBuilder sb = new StringBuilder();
			for (NameValuePair p : parameters) {
				BasicNameValuePair b = (BasicNameValuePair) p;
				sb.append("&").append(p.getName()).append("=")
						.append(p.getValue());
			}
			logger.info("==================>baihe_other_arguments："
					+ sb.toString());
			
			String result = HttpRequest
					.executePost(
							"http://xact.baihe.com/Lovebankcallback/HjBuy",
							parameters, null);
			logger.info("==================>baihe_other_callback："
					+ result);
			if (isNoneBlank(result)) {
				commonService.setMongodbForValue("Baihe_Other_Callback_" + financing.getOrder().getOrderNumber(), result);
			}
			
			parameters = new ArrayList<NameValuePair>();
			parameters.add(new BasicNameValuePair("userName",financing.getUser().getRealName()));
			parameters.add(new BasicNameValuePair("sign",Encryption.getMD5("e02bde5fedef350e"+ financing.getUser().getMobile())));
			parameters.add(new BasicNameValuePair("userMobile",financing.getUser().getMobile()));
			
			sb = new StringBuilder();
			for (NameValuePair p : parameters) {
				BasicNameValuePair b = (BasicNameValuePair) p;
				sb.append("&").append(p.getName()).append("=")
						.append(p.getValue());
			}
			logger.info("==================>baihe_modify_user_arguments："
					+ sb.toString());
			result = HttpRequest
					.executePost(
							"http://xact.baihe.com/Lovebankcallback/HjModify",
							parameters, null);
			logger.info("==================>baihe_modify_user_callback："
					+ result);
			if (isNoneBlank(result)) {
				commonService.setMongodbForValue("Baihe_User_Modify_Callback_" + financing.getUser().getMobile(), result);
			}
		}
	}

	@Override
	public void handleBaiheRegisterBusiness(User user) {
		boolean needBaiheCallback = false;
		Invitation invitation = null;
		List<String> list = (List<String>) commonService.getMongodbForValue("Baihe_Employee_Mobile_Number");
		//如果是百合注册的就认为需要返回
		if("baihe".equalsIgnoreCase(user.getReferee())){
			needBaiheCallback = true;
		}else if(list.contains(user.getMobile())){//如果是百合的种子用户就认为需要返回
			needBaiheCallback = true;
		} else {
			InvitationExample example = new InvitationExample();
			example.appendCriterion("`invitee_id`=", user.getId());
			invitation = this.invitationMapper.selectOneByExample(example);
			if(null != invitation){
				if(list.contains(invitation.getInviter().getMobile())){
					needBaiheCallback = true;
				}
			}
		}
		if(needBaiheCallback){
			List<NameValuePair> parameters = new ArrayList<NameValuePair>();
			parameters.add(new BasicNameValuePair("userId",isNoneBlank(user.getOpenId())?user.getOpenId():"0"));
			parameters.add(new BasicNameValuePair("userName","无"));
			parameters.add(new BasicNameValuePair("userMobile",user.getMobile()));
			parameters.add(new BasicNameValuePair("createDate",user.getCreateDate().getTime() + ""));
			parameters.add(new BasicNameValuePair("userCard","0"));
			parameters.add(new BasicNameValuePair("Development","0"));
			parameters.add(new BasicNameValuePair("sign",Encryption.getMD5("e02bde5fedef350e"+ user.getMobile())));
			
			StringBuilder sb = new StringBuilder();
			for (NameValuePair p : parameters) {
				BasicNameValuePair b = (BasicNameValuePair) p;
				sb.append("&").append(p.getName()).append("=")
						.append(p.getValue());
			}
			logger.info("==================>baihe_register_arguments："
					+ sb.toString());
			
			String result = HttpRequest
					.executePost(
							"http://xact.baihe.com/Lovebankcallback/HjOpen",
							parameters, null);
			logger.info("==================>baihe_register_callback："
					+ result);
			if (isNoneBlank(result)) {
				commonService.setMongodbForValue("Baihe_Register_Callback_" + user.getMobile(), result);
			}
			
			if(null!=invitation){
				InvitationExample example = new InvitationExample();
				example.appendCriterion("`inviter_id`=", invitation.getInviter().getId());
				int count = this.invitationMapper.countByExample(example);
				
				parameters = new ArrayList<NameValuePair>();
				parameters.add(new BasicNameValuePair("sign",Encryption.getMD5("e02bde5fedef350e"+ invitation.getInviter().getMobile())));
				parameters.add(new BasicNameValuePair("userMobile",invitation.getInviter().getMobile()));
				parameters.add(new BasicNameValuePair("Development",String.valueOf(count)));
				
				sb = new StringBuilder();
				for (NameValuePair p : parameters) {
					BasicNameValuePair b = (BasicNameValuePair) p;
					sb.append("&").append(p.getName()).append("=")
							.append(p.getValue());
				}
				logger.info("==================>baihe_modify_user_arguments："
						+ sb.toString());
				result = HttpRequest
						.executePost(
								"http://xact.baihe.com/Lovebankcallback/HjModify",
								parameters, null);
				logger.info("==================>baihe_modify_user_callback："
						+ result);
				if (isNoneBlank(result)) {
					commonService.setMongodbForValue("Baihe_User_Modify_Callback_" + invitation.getInviter().getMobile(), result);
				}
			}
		}
	}

	@Override
	public void handleHejiaLotteryBusiness(Financing financing) {
		JSONObject config = getActivityConfig("2015_HEJIA_ONEYEAR_ACTIVITY_CONFIG").getJSONObject("lottery-config");
		String starting_date = config.getString("starting-date"), expiring_date = config.getString("expiring-date"), mydate = formatDate(financing.getCreateDate());
		if (mydate.compareTo(starting_date) >= 0
				&& mydate.compareTo(expiring_date) <= 0) {
			if(TRACK_HJ_MM_HEJIA_LOTTERY.equalsIgnoreCase(financing.getTrack())){
				switch (financing.getProduct().getCategory()) {
				case QUARTER:
				case HALF_A_YEAR:
				case YEAR:
					int amount = financing.getAmount().intValue();
					Integer totalAmount = (Integer) commonService.getMongodbForValue(MONGODB_KEY_HEJIA_LOTTERY_ACCUMULATED_AMOUNT + financing.getUser().getId());
					if(null == totalAmount){
						totalAmount = 0;
					}
					totalAmount += amount;
					commonService.setMongodbForValue(MONGODB_KEY_HEJIA_LOTTERY_ACCUMULATED_AMOUNT + financing.getUser().getId(), totalAmount);
					//查询用户已经获得的抽奖次数
					QualificationExample example = new QualificationExample();
					example.appendCriterion("`type`=", Qualification.TYPE_HEJIA_ONEYEAR_LOTTERY);
					example.appendCriterion("`user_id`=", financing.getUser().getId());
					int userCount = findQualificationCountByExample(example),
					count = totalAmount / 10000,//总共有几次抽奖机会
					remains = count - userCount;
					if(remains>0){
						//把抽奖机会放入数据库中
						for (int i = 0; i < remains; i++) {
							Qualification qualification = new Qualification();
							qualification.setCreateDate(new Date());
							qualification.setModifyDate(qualification.getCreateDate());
							qualification.setUser(financing.getUser());
							qualification.setType(Qualification.TYPE_HEJIA_ONEYEAR_LOTTERY);
							qualification.setUsed(false);
							commonService.insertQualification(qualification);
						}
					}
					break;
				default:
					break;
				}
			}
		}
	}

	@Override
	public BigDecimal getFinancingStat(User user) {
		FinancingExample example = new FinancingExample();
		example.appendCriterion("user_id=", user.getId());
		example.appendCriterion("createDate >", "2016-5-25");
		example.appendCriterion("createDate <", "2016-6-6");
		List<Financing> list = financingMapper.selectByExample(example, new Pager<Financing>());
		BigDecimal total = new BigDecimal(0);
		for(Financing financing : list){
			total = total.add(financing.getAmount());
		}
		
		return total;
	}

	@Override
	public Map<String, Integer> getInvitationStat(User user) {
		InvitationExample example = new InvitationExample();
		example.appendCriterion("inviter_id=", user.getId());
		example.appendCriterion("createDate >", "2016-5-25");
		example.appendCriterion("createDate <", "2016-6-6");
		List<Invitation> list = invitationMapper.selectByExample(example, new Pager<Invitation>());
		Integer registerCount = 0;
		Integer buyerCount = 0;
		for(Invitation invitation : list){
			registerCount++;
			if(new Double(50).equals(invitation.getAmount()))
				buyerCount++;
		}
		Map<String, Integer> result = new HashMap<String, Integer>();
		result.put("registerCount", registerCount);
		result.put("buyerCount", buyerCount);
		return result;
	}

	@Override
	public Address getAddressByUser(User user) {
		AddressExample example = new AddressExample();
		example.appendCriterion("user_id=", user.getId());
		return addressMapper.selectOneByExample(example);
	}
	
	@Override
	public Boolean DBFAward2016(User user, String awardCode){
		
		String award = "";
		switch(awardCode){
			case "DBF_3W":
				BigDecimal amount = this.getFinancingStat(user);
				if(amount.compareTo(new BigDecimal(30000)) >= 0)
					award = "满3万送粽子";
				else
					return false;
				break;
				
			case "DBF_8W":
				BigDecimal amount8 = this.getFinancingStat(user);
				if(amount8.compareTo(new BigDecimal(80000)) >= 0)
					award = "满8万送粽子";
				else
					return false;
				
				break;
			case "DBF_INVITE":
				Integer buyerCount = this.getInvitationStat(user).get("buyerCount");
				if(buyerCount >=5){
					award = "邀请满5人送粽子";
				}else
					return false;
				break;
			default:
				return false;
		}
		
		Qualification qualification = new Qualification();
		qualification.setUser(user);
		qualification.setAward(award);
		qualification.setAwardCode(awardCode);
		return commonService.insertQualification(qualification) > 0;
	}
	
	@Override
	public Boolean findQualificationRecord(User user, String awardCode){
		QualificationExample qualExamplie = new QualificationExample();
		qualExamplie.appendCriterion("user_id = ", user.getId());
		qualExamplie.appendCriterion("awardCode = ", awardCode);
		List<Qualification> result = commonService.findQualificationsByExample(qualExamplie);
		return result!=null && result.size()>0;
	}
	
	
}
